#include "kernel/smp/smp.h"
#include "kernel/smp/cpu.h"
#include "libs/types.h"
#include "libs/msr.h"
#include "libs/lib.h"
#include "kernel/apic/apic.h"
#include "kernel/interrupt/interrupt.h"
#include "kernel/memory/memory.h"
#include "kernel/log/log.h"
#include "kernel/task/task.h"
#include "kernel/apic/ipi.h"


extern "C" char _APU_BOOT_START[];
extern "C" char _APU_BOOT_END[];


SmpManager* SmpManager::smpm = 0;






SmpManager::SmpManager(/* args */)
{
    
    // SpinlockInit(&smpSpinlock);
    smpm = this;
    // INT_CMD_REG icr_entry;
    // isSMP = 1;
    // init BSP TSS
    uint64_t* ptr = (uint64_t*)((uint64_t)MEMORY->kmalloc(STACK_SIZE,0) + STACK_SIZE);
    ((task*)(ptr - STACK_SIZE))->cpuId = 0;
    init_tss[0].IST2 = (uint64_t)ptr;
    
    ptr = (uint64_t*)((uint64_t)MEMORY->kmalloc(STACK_SIZE,0) + STACK_SIZE);
    ((task*)(ptr - STACK_SIZE))->cpuId = 0;
    init_tss[0].IST1 = (uint64_t)ptr;
    ptr = (uint64_t*)((uint64_t)MEMORY->kmalloc(STACK_SIZE,0) + STACK_SIZE);
    ((task*)(ptr - STACK_SIZE))->cpuId = 0;
    init_tss[0].IST3 = (uint64_t)ptr;
    init_tss[0].IST4 = (uint64_t)ptr;
    init_tss[0].IST5 = (uint64_t)ptr;
    init_tss[0].IST6 = (uint64_t)ptr;
    init_tss[0].IST7 = (uint64_t)ptr;
    LOG_ERROR("ist1 address:%lx\n",init_tss[0].IST1);
    LOG_ERROR("ist2 address:%lx\n",init_tss[0].IST2);
    LOG_ERROR("ist3 address:%lx\n",init_tss[0].IST3);
    // icr_entry.vector = 0x00;
	// icr_entry.deliver_mode =  APIC_ICR_IOAPIC_INIT;
	// icr_entry.dest_mode = ICR_IOAPIC_DELV_PHYSICAL;
	// icr_entry.deliver_status = APIC_ICR_IOAPIC_Idle;
	// icr_entry.res_1 = 0;
	// icr_entry.level = ICR_LEVEL_DE_ASSERT;
	// icr_entry.trigger = APIC_ICR_IOAPIC_Edge;
	// icr_entry.res_2 = 0;
	// icr_entry.dest_shorthand = ICR_ALL_EXCLUDE_Self;
	// icr_entry.res_3 = 0;
	// icr_entry.destination.x2apic_destination = 0x00;
    // memcpy(_APU_BOOT_START,(void*)0xffff800000020000,_APU_BOOT_END - _APU_BOOT_START);
    // wrmsr(IA32_APIC_ICR,*(uint64_t*)&icr_entry); //0100 0101

    // for(uint8_t i = 1; i < 2;i++){
        

    //     SpinlockLock(&smpSpinlock);

    //     icr_entry.vector = 0x20;
    //     icr_entry.deliver_mode = ICR_Start_up;
    //     icr_entry.dest_shorthand = ICR_No_Shorthand;
    //     icr_entry.destination.x2apic_destination = i;

    //     wrmsr(IA32_APIC_ICR,*(uint64_t*)&icr_entry);
    //     wrmsr(IA32_APIC_ICR,*(uint64_t*)&icr_entry); //0100 0110 0010 0000  起始地址0x20000
    // }
    
    // IPIMANAGER->sendIpi(0x1,0xCB);
    // SMPMANAGER->isHaveFinish	 = 1;
}




SmpManager::~SmpManager()
{


}
